package org.example.mall.admin.configuration.resource;

import lombok.AllArgsConstructor;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.CorsConfigurer;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.Arrays;
import java.util.Collections;

/**
 * 资源服务器配置
 *
 * @author hzq
 * @date 2021/12/7 21:27
 */
@Configuration
@AllArgsConstructor
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableConfigurationProperties(PermitAllUrl.class)
public class CustomResourceServerConfiguration extends ResourceServerConfigurerAdapter {

    private final PermitAllUrl permitAllUrl;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources.tokenExtractor(CustomBearerTokenExtractor.build(permitAllUrl));
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {

        ExpressionUrlAuthorizationConfigurer<HttpSecurity>
                .ExpressionInterceptUrlRegistry registry = http.authorizeRequests();

        permitAllUrl.registryAntMatchers(registry);

        registry.anyRequest().authenticated()
                .and()
                .cors(corsCustomizer())
                .csrf().disable();
    }

    Customizer<CorsConfigurer<HttpSecurity>> corsCustomizer() {
        return (c) -> {
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            CorsConfiguration corsConfiguration = new CorsConfiguration();
            corsConfiguration.setAllowedOriginPatterns(Collections.singletonList(CorsConfiguration.ALL));
            corsConfiguration.setAllowCredentials(Boolean.TRUE);
            corsConfiguration.addAllowedHeader(CorsConfiguration.ALL);
            corsConfiguration.addAllowedMethod(CorsConfiguration.ALL);
            source.registerCorsConfiguration("/**", corsConfiguration);
            c.configurationSource(source);
        };
    }
}
